跳到主要内容

事件

事件其实是包含“事件”与“触发器”2个部分。你可以在任意对象上以某个事件名注册触发器,当该对象以该事件发起出事件时,便会被触发器接收到。发起事件时可以传入N个自定义参数,这些参数会被触发器接收到。你可以给同一个对象的某个事件名下注册多个触发器,当发起事件时,这些触发器会按照注册顺序反序执行。在这些触发器依次执行的过程中,删除一个还在排队等待执行的触发器,那么它将不会执行;新建该事件名的触发器,那么它本次也不会执行。

-- 发起一个事件,自定义参数为...
base.event_notify(obj, name, ...)

-- 也可以用这个方法来发起事件,区别之后再讲
base.event_dispatch(obj, name, ...)

-- 这个事件会被该触发器接收到
base.event_register(obj, name, function (trigger, ...)
-- 接收到的自定义参数为...
end)

为了方便起见,我们将一些常用对象做了封装

全局事件。

-- 发起
base.game:event_notify(name, ...)
base.game:event_dispatch(name, ...)

-- 接收
base.game:event(name, function (trigger, ...)
end)

玩家事件,玩家事件发起完毕后会使用同样的参数再发起一次全局事件。

-- 发起
player:event_notify(name, ...)
player:event_dispatch(name, ...)

-- 接收
player:event(name, function (trigger, ...)
end)
base.game:event(name, function (trigger, ...)
end)

单位事件,玩家事件发起完毕后会使用同样的参数再发起一次玩家事件和一次全局事件,发起玩家事件时玩家为单位的控制者

-- 发起
unit:event_notify(name, ...)
unit:event_dispatch(name, ...)

-- 接收
unit:event(name, function (trigger, ...)
end)
unit:get_owner():event(name, function (trigger, ...)
end)
base.game:event(name, function (trigger, ...)
end)

event_notifyevent_dispatch的区别在于,event_dispatch可以获取到触发器的返回值:当接收事件的触发器返回了一个非nil的值后,当前事件将被终止,并将返回值返回给event_dispatch的调用方。而event_notify的事件则无法被终止,也不关心返回值。

base.game:event('加法', function (trigger, a, b)
return a + b
end)

local result = base.game:event_dispatch('加法', 1, 2)
print(result) --> 3

方法

event_register

注册事件

  • 参数
    • object (table/userdata) - 对象
    • name (string) - 事件名
    • callback (function) - 回调函数
  • 返回
    • trigger (trigger) - 触发器对象
  • 回调参数
    • trigger (trigger) - 触发器对象
    • ... (...) - 自定义数据
  • 回调返回
    • ... (...) - 自定义返回值(只有使用event_dispatch时有意义)

event_dispatch

发起事件(关心返回值)

  • 参数
    • name (string) - 事件名
    • obj (table/userdata) - 对象
    • ... (...) - 自定义数据

event_notify

发起事件(不关心返回值)

  • 参数
    • name (string) - 事件名
    • obj (table/userdata) - 对象
    • ... (...) - 自定义数据

内置事件

框架内置了许多事件,有些事件是通过event_dispatch发起的,意味着你可以给他设置返回值,这些事件会特别说明。

单位-初始化

  • 参数
    • unit (unit) - 创建的单位

此时单位还未添加技能,在这个事件中给单位添加技能可以阻止 HeroSkillHideSkill 中的同槽位技能。

注意,此事件触发时该单位刚被创建,他会在当帧的后半阶段被同步给能看见他的玩家(包括自己)的客户端,因此,不要在初始化事件中立即该单位的id同步给客户端(包括使用player:set_hero也是一样效果),或者客户端拿到了不要立即使用(下一帧使用即可)。因为此时客户端还没有收到该单位出现在视野的协议,立即使用可能会有些问题。

base.game:event('单位-初始化', function (trg, unit)
end)

单位-创建

  • 参数
    • unit (unit) - 创建的单位

此时技能已经添加完毕,如果是镜像的话单位属性也已经复制完毕。

单位-初始化事件一样,单位本身此时还没有本同步给客户端。因此,不要在客户端立即使用该单位。下一帧再使用是可以的。

base.game:event('单位-创建', function (trg, unit)
end)

单位-即将死亡

  • 参数
    • damage (damage) - 即将杀死单位的伤害

当单位即将因为受到伤害而死亡时会触发此事件,返回 false 可以阻止单位被杀死。

unit:event('单位-即将死亡', function (trg, damage)
return false
end)

单位-死亡

  • 参数
    • dead (unit) - 死者
    • killer (unit) - 凶手

此时单位已经死亡。

unit:event('单位-死亡', function (trg, unit, killer)
end)

单位-复活

  • 参数
    • unit (unit) - 复活的单位

此时单位已经复活。

unit:event('单位-复活', function (trg, unit)
end)

单位-升级

  • 参数
    • unit (unit) - 升级的单位

此时单位已经升级。

!> 在该事件中,单位的经验有可能大于经验上限

unit:event('单位-升级', function (trg, unit)
end)

单位-即将获得状态

  • 参数
    • u (unit) - 获得状态的单位
    • buff (buff) - 获得的状态

返回false可以阻止获得状态。

unit:event('单位-即将获得状态', function (trg, u , buff)
return false
end)

单位-获得状态

  • 参数
    • u (unit) - 获得状态的单位
    • buff (buff) - 获得的状态

此时单位已经获得状态。

unit:event('单位-获得状态', function (trg, u , buff)
end)

单位-购买物品

  • 参数
    • unit (unit) - 购买物品的单位
    • name (string) - 要购买的物品名

这是客户端请求购买物品的事件,由脚本库使用。

unit:event('单位-购买物品', function (trg, unit, name)
end)

单位-出售物品

  • 参数
    • unit (unit) - 出售物品的单位
    • slot (integer) - 物品槽位ID

这是客户端请求出售物品的事件,由脚本库使用。

unit:event('单位-出售物品', function (trg, unit, slot)
end)

单位-撤销物品

  • 参数
    • unit (unit) - 撤销物品的单位

这是客户端请求撤销物品的事件,由脚本库使用。

unit:event('单位-撤销物品', function (trg, unit)
end)

单位-获得物品

  • 参数
    • unit (unit) - 获得物品的单位
    • item (item) - 获得的物品
unit:event('单位-获得物品', function (trg, unit, item)
end)

单位-失去物品

  • 参数
    • unit (unit) - 失去物品的单位
    • item (item) - 失去的物品
unit:event('单位-失去物品', function (trg, unit, item)
end)

单位-丢弃物品

  • 参数
    • unit (unit) - 丢弃物品的单位
    • slot (integer) - 物品槽位ID
    • target (point) - 丢弃位置

这是客户端请求丢弃物品的事件,由脚本库使用。

unit:event('单位-丢弃物品', function (trg, unit, slot, target)
end)

单位-攻击开始

  • 参数
    • damage (damage) - 此次攻击的伤害

在该事件中设置damage.crit_flag = true可以令本次攻击使用暴击动画和暴击特效。

unit:event('单位-攻击开始', function (trg, damage)
damage.crit_flag = true
end)

单位-攻击出手

  • 参数
    • damage (damage) - 此次攻击的伤害
unit:event('单位-攻击出手', function (trg, damage)
end)

单位-请求命令

  • 参数
    • unit (unit) - 请求命令的单位
    • command (string) - 命令,可能的值有:
      • stop - 停止
      • walk - 移动
      • attack - 攻击
      • walk-attack - 攻击移动
      • 技能名 - 想要使用这个技能
    • target (unit/point/nil) - 命令目标,他的类型由命令决定:
      • stop - nil
      • walk - unit/point
      • attack - unit
      • walk-attack - point
      • 技能名 - 由技能的目标类型决定
    • state (integer) - 组合键

只有来自客户端的命令才会触发此事件,返回false可以阻止命令。如果用户发布命令时按住了Alt键,则state为1。

unit:event('单位-请求命令', function (trg, unit, command, target, state)
return false
end)

单位-发布命令

  • 参数
    • unit (unit) - 发布命令的单位
    • command (string) - 命令,可能的值有:
      • stop - 停止
      • walk - 移动
      • attack - 攻击
      • walk-attack - 攻击移动
      • 技能名 - 想要使用这个技能
    • target (unit/point/nil) - 命令目标,他的类型由命令决定:
      • stop - nil
      • walk - unit/point
      • attack - unit
      • walk-attack - point
      • 技能名 - 由技能的目标类型决定
    • state (integer) - 组合键

只有来自客户端的命令才会触发此事件,触发此事件时单位还没有执行此命令。如果用户发布命令时按住了Alt键,则state为1。

unit:event('单位-发布命令', function (trg, unit, command, target, state)
end)

单位-执行命令

  • 参数
    • unit (unit) - 执行命令的单位
    • command (string) - 命令,可能的值有:
      • stop - 停止
      • walk - 移动
      • attack - 攻击
      • walk-attack - 攻击移动
      • 技能名 - 想要使用这个技能
    • target (unit/point/nil) - 命令目标,他的类型由命令决定:
      • stop - nil
      • walk - unit/point
      • attack - unit
      • walk-attack - point
      • 技能名 - 由技能的目标类型决定
    • state (integer) - 组合键

只有来自客户端的命令才会触发此事件,触发此事件时单位已经执行此命令。如果用户发布命令时按住了Alt键,则state为1。

unit:event('单位-执行命令', function (trg, unit, command, target, state)
end)

单位-移动

  • 参数
    • unit (unit) - 移动的单位
    • last_point (point) - 之前的位置
    • next_point (point) - 即将要去的位置

单位移动时每帧触发一次,因此不要过多的注册此事件。

unit:event('单位-移动', function (trg, unit, last_point, next_point)
end)

单位-着陆

  • 参数
    • unit (unit) - 着陆的单位
    • z_speed (float) - 着陆那一刻z轴的速度,必定是负数
unit:event('单位-着陆', function (trg, unit, z_speed)
end)

单位-撞头

  • 参数
    • unit (unit) - 撞头的单位(头上有障碍,跳起来的时候撞到了)
    • z_speed (float) - 撞头那一刻z轴的速度,必定是正数
unit:event('单位-撞头', function (trg, unit, z_speed)
end)

单位-学习技能

  • 参数
    • unit (unit) - 学习技能的单位
    • skill (skill) - 要学习的技能

单位想要学习技能时触发。脚本库会根据技能是否可以学习、单位是否拥有技能点等规则尝试升级技能并扣除技能点。你可以通过注册这个事件来实现自定义的学习技能规则,返回一个非nil值来阻止脚本库的默认行为。

unit:event('单位-学习技能', function (trg, unit, skill)
return false
end)

单位-学习技能完成

  • 参数
    • unit (unit) - 学习技能的单位
    • skill (skill) - 学习的技能

脚本库成功学习一个技能后触发。

unit:event('单位-学习技能完成', function (trg, unit, skill)
end)

单位-即将获得经验

  • 参数
    • unit (unit) - 单位
    • data (data) - 数据
      • exp (number) - 经验值

当使用add_exp给单位增加经验时触发,修改exp可以修改获得的经验。

unit:event('单位-即将获得经验', function (trg, data)
data.exp = data.exp * 2.0
end)

单位-获得经验

  • 参数
    • unit (unit) - 单位
    • data (data) - 数据
      • exp (number) - 经验值

当使用add_exp给单位增加经验时触发,此时经验已经增加完毕。

unit:event('单位-获得经验', function (trg, data)
end)

技能-获得

  • 参数
    • unit (unit) - 获得技能的单位
    • skill (skill) - 获得的技能
unit:event('技能-获得', function (trg, unit, skill)
end)

技能-失去

  • 参数
    • unit (unit) - 失去技能的单位
    • skill (skill) - 失去的技能
unit:event('技能-失去', function (trg, unit, skill)
end)

技能-即将施法

  • 参数
    • unit (unit) - 施法单位
    • cast (skill) - 施法对象

返回false可以阻止施法。接着还可以返回一个字符串,这个字符串会显示在客户端上,告诉玩家为何阻止施法。

unit:event('技能-即将施法', function (trg, unit, cast)
return false, '你的爱不够'
end)

技能-即将打断

  • 参数
    • unit (unit) - 施法单位
    • cast (skill) - 当前施法
    • new (skill) - 新的施法

只有当处于施法状态时,尝试使用发动另一个技能才会触发此事件。返回false表示不允许打断。

unit:event('技能-即将打断', function (trg, unit, cast, new)
if new:get_name() ~= '二段施法' then
return false
end
new['一段施法'] = cast
end)

技能-施法开始

  • 参数
    • unit (unit) - 施法单位
    • cast (skill) - 施法对象
unit:event('技能-施法开始', function (trg, unit, cast)
end)

技能-施法打断

  • 参数
    • unit (unit) - 施法单位
    • cast (skill) - 施法对象
unit:event('技能-施法打断', function (trg, unit, cast)
end)

技能-施法引导

  • 参数
    • unit (unit) - 施法单位
    • cast (skill) - 施法对象
unit:event('技能-施法引导', function (trg, unit, cast)
end)

技能-施法出手

  • 参数
    • unit (unit) - 施法单位
    • cast (skill) - 施法对象
unit:event('技能-施法出手', function (trg, unit, cast)
end)

技能-施法完成

  • 参数
    • unit (unit) - 施法单位
    • cast (skill) - 施法对象
unit:event('技能-施法完成', function (trg, unit, cast)
end)

技能-施法停止

  • 参数
    • unit (unit) - 施法单位
    • cast (skill) - 施法对象
unit:event('技能-施法停止', function (trg, unit, cast)
end)

技能-施法失败

  • 参数

    • unit (unit) - 施法单位
    • cast (skill) - 施法对象
    • failed_code(number) 施法失败错误码

    施法失败的出发时机和失败枚举值, 参见on_cast_failed

unit:event('技能-施法失败', function (trg, unit, cast, failed_code)
end)

技能-冷却完成

  • 参数
    • unit (unit) - 拥有技能的单位
    • skill (skill) - 完成冷却的技能
unit:event('技能-冷却完成', function (trg, unit, skill)
end)

玩家-输入作弊码

  • 参数
    • player (player) - 输入作弊码的玩家
    • command (string) - 输入的作弊码

只有在测试模式下会触发此事件。用户输入以-开头的聊天消息后触发,作弊码内容为第2个字符开始的聊天消息。

player:event('玩家-输入作弊码', function (trg, player, command)
end)

玩家-输入聊天

  • 参数
    • player (player) - 输入聊天的玩家
    • chat (string) - 聊天内容
player:event('玩家-输入聊天', function (trg, player, chat)
end)

玩家-选择英雄

  • 参数
    • player (player) - 选择英雄的玩家
    • name (string) - 英雄名

玩家在选人界面选择英雄后触发此事件。

player:event('玩家-选择英雄', function (trg, player, name)
local hero = player:create_unit(name, point, face)
end)

玩家-连入

  • 参数
    • player (player) - 重连的玩家
    • is_reconnect (bool) - 是否是经过重连进入的游戏
player:event('玩家-连入', function (trg, player, is_reconnect)
end)

玩家-断线

  • 参数
    • player (player) - 断线的玩家
player:event('玩家-断线', function (trg, player)
end)

玩家-重连

这个事件已经被标记为过时, 将在以后的某个时间被删除 请使用玩家-连入事件替代

  • 参数
    • player (player) - 重连的玩家
player:event('玩家-重连', function (trg, player)
end)

玩家-放弃重连

  • 参数
    • player (player) - 放弃重连的玩家

触发此事件意味着该玩家再也不会重连回游戏了。

player:event('玩家-放弃重连', function (trg, player)
end)

玩家-暂时离开

  • 参数
    • player (player) - 触发事件的玩家

当玩家到游戏服务器的连接断开之后不会马上断线(也不会触发服务器的断线事件),而是进入暂时离开状态,服务器会保留它的一些信息(现在主要是kcp的数据),玩家再连接并且使用原来的kcp会话号就可以重新回到游戏。在这个状态超时之后会触发断线事件,进入断线状态,目前时间是5分钟

player:event('玩家-暂时离开', function (trg, player)
end)

玩家-回到游戏

  • 参数
    • player (player) - 触发事件的玩家

暂时离开状态的玩家连接到服务器,并使用之前的连接信息进行通信,会触发回到游戏事件

player:event('玩家-回到游戏', function (trg, player)
end)

玩家-小地图信号

  • 参数
    • player (player) - 发送信号的玩家
    • data (table) - 信号数据
      • player (player) - 发送信号的玩家
      • name (string) - 信号名,定义在 Constant.ini
      • target (unit/point) - 目标
      • time (integer) - 持续时间(毫秒)

玩家请求发送小地图信号时触发此事件。修改信号数据中的属性可以修改本次信号。在事件中返回false可以阻止此信号。

player:event('玩家-小地图信号', function (trg, player, data)
if data.name == '撤退' then
data.name = '进攻'
data.target = data.target:get_point()
data.time = 1000
elseif data.name == '求救' then
return false
end
end)

玩家-暂停游戏

  • 参数
    • player (player) - 想要暂停游戏的玩家

当玩家请求暂停游戏时触发,返回false可以阻止暂停。

player:event('玩家-暂停游戏', function (trg, player)
return false
end)

玩家-恢复游戏

  • 参数
    • player (player) - 想要恢复游戏的玩家

当玩家请求恢复游戏时触发,返回false可以阻止恢复。

player:event('玩家-恢复游戏', function (trg, player)
return false
end)

玩家-界面消息

  • 参数
    • player (player) - 发送消息的玩家
    • stream (string) - 消息内容

用于脚本库与界面通讯。

player:event('玩家-界面消息', function (trg, player, stream)
end)

游戏-阶段切换

base.game:event('游戏-阶段切换', function (trg)
local status = base.game:status()
end)

伤害初始化

  • 参数
    • damage (damage) - 伤害

用于脚本库实现法球。

base.event_register(damage, '伤害初始化', function (trg, damage)
end)

造成伤害开始

  • 参数
    • damage (damage) - 伤害

订阅对象是单位。此时伤害还没有结算,返回false可以阻止此伤害。

unit:event('造成伤害开始', function (trg, damage)
return false
end)

受到伤害开始

  • 参数
    • damage (damage) - 伤害

订阅对象是单位。此时伤害还没有结算,返回false可以阻止此伤害。

unit:event('受到伤害开始', function (trg, damage)
return false
end)

造成伤害

  • 参数
    • damage (damage) - 伤害

订阅对象是单位。此时已经计算了护甲,但是还没有结算。你可以在这里修改伤害值。特别说明,你可以在这里将伤害值设置回初始伤害,以实现无视护甲的效果。

unit:event('造成伤害', function (trg, damage)
damage:set_current_damage(damage:get_current_damage() * 2.0)
end)

受到伤害

  • 参数
    • damage (damage) - 伤害

订阅对象是单位。此时已经计算了护甲,但是还没有结算。你可以在这里修改伤害值。特别说明,你可以在这里将伤害值设置回初始伤害,以实现无视护甲的效果。

unit:event('受到伤害', function (trg, damage)
damage:set_current_damage(damage:get_damage())
end)

伤害前效果

  • 参数
    • damage (damage) - 伤害

用于脚本库实现法球。

base.event_register(damage, '伤害前效果', function (trg, damage)
end)

法球开始

  • 参数
    • damage (damage) - 伤害

订阅对象是单位,用于脚本库实现法球。

unit:event('法球开始', function (trg, damage)
end)

法球出手

  • 参数
    • damage (damage) - 伤害

订阅对象是单位,用于脚本库实现法球。

unit:event('法球出手', function (trg, damage)
end)

玩家-切换场景

  • 参数
    • player
    • scene_name

单位-切换场景

  • 参数
    • unit
    • scene_name

游戏-加载场景

  • 参数
    • scene_name

游戏-开始

游戏开始的时候触发

游戏-装备局开始

装备局开始时触发